"""
数据库元数据API路由
提供表结构和列信息的查询接口
"""

from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.orm import Session

from src.models.database_metadata import (
    DatabaseMetadataResponse, TableMetadata, TableStats
)
from src.models.generic_filter import TableQueryInfo
from src.services.database_metadata_service import DatabaseMetadataService
from src.services.generic_query_service import GenericQueryService
from src.config.database import get_db
from src.utils.logging import get_logger

router = APIRouter(prefix="/database", tags=["database"])
logger = get_logger(__name__)


@router.get("/metadata", response_model=DatabaseMetadataResponse)
async def get_database_metadata(
    db: Session = Depends(get_db)
):
    """获取整个数据库的元数据信息"""
    try:
        return DatabaseMetadataService.get_all_tables_metadata(db)
    except Exception as e:
        logger.error(f"获取数据库元数据失败: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"获取数据库元数据失败: {str(e)}"
        )


@router.get("/tables/{table_name}/metadata", response_model=TableMetadata)
async def get_table_metadata(
    table_name: str,
    db: Session = Depends(get_db)
):
    """获取特定表的元数据信息"""
    try:
        metadata = DatabaseMetadataService.get_table_metadata(db, table_name)
        if metadata is None:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail=f"表 '{table_name}' 不存在"
            )
        return metadata
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取表 {table_name} 元数据失败: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"获取表元数据失败: {str(e)}"
        )


@router.get("/tables", response_model=List[str])
async def list_tables(
    db: Session = Depends(get_db)
):
    """获取所有表名列表"""
    try:
        inspector = db.get_bind().execution_options().get_inspector()
        return inspector.get_table_names()
    except Exception as e:
        logger.error(f"获取表列表失败: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"获取表列表失败: {str(e)}"
        )


@router.get("/tables/{table_name}/columns")
async def get_table_columns(
    table_name: str,
    db: Session = Depends(get_db)
):
    """获取表的列信息"""
    try:
        return GenericQueryService.get_table_columns(db, table_name)
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取表 {table_name} 列信息失败: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"获取列信息失败: {str(e)}"
        )


@router.get("/tables/{table_name}/stats", response_model=TableStats)
async def get_table_stats(
    table_name: str,
    db: Session = Depends(get_db)
):
    """获取表的统计信息"""
    try:
        # 验证表是否存在
        inspector = db.get_bind().execution_options().get_inspector()
        if table_name not in inspector.get_table_names():
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail=f"表 '{table_name}' 不存在"
            )
        
        # 获取行数
        row_count = DatabaseMetadataService._get_table_row_count(db, table_name)
        
        # 获取表大小（简化处理，实际实现可能需要数据库特定的查询）
        size_mb = 0.0  # 默认值
        
        return TableStats(
            table_name=table_name,
            row_count=row_count or 0,
            size_mb=size_mb
        )
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"获取表 {table_name} 统计信息失败: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"获取统计信息失败: {str(e)}"
        )


@router.get("/models/metadata", response_model=List[TableMetadata])
async def get_sqlalchemy_models_metadata():
    """获取所有SQLAlchemy模型的元数据信息"""
    try:
        return DatabaseMetadataService.get_sqlalchemy_models_metadata()
    except Exception as e:
        logger.error(f"获取SQLAlchemy模型元数据失败: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"获取模型元数据失败: {str(e)}"
        )


@router.get("/query-info", response_model=List[TableQueryInfo])
async def get_query_info(
    table_names: Optional[List[str]] = Query(None),
    db: Session = Depends(get_db)
):
    """获取表的查询信息（用于前端构建查询界面）"""
    try:
        result = []
        
        # 如果没有指定表名，获取所有表
        if not table_names:
            inspector = db.get_bind().execution_options().get_inspector()
            table_names = inspector.get_table_names()
        
        for table_name in table_names:
            try:
                columns_info = GenericQueryService.get_table_columns(db, table_name)
                
                # 获取主键信息
                inspector = db.get_bind().execution_options().get_inspector()
                pk_info = inspector.get_pk_constraint(table_name)
                primary_keys = pk_info.get('constrained_columns', [])
                
                columns = []
                for col_info in columns_info:
                    columns.append({
                        'name': col_info['name'],
                        'type': col_info['type'],
                        'nullable': col_info['nullable']
                    })
                
                result.append({
                    'table_name': table_name,
                    'columns': columns,
                    'primary_keys': primary_keys
                })
                
            except Exception as e:
                logger.warning(f"获取表 {table_name} 查询信息失败: {e}")
                continue
        
        return result
        
    except Exception as e:
        logger.error(f"获取查询信息失败: {e}")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"获取查询信息失败: {str(e)}"
        )
